﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GameEngine.PositionConverter
{
    /// <summary>
    /// Base position converter
    /// </summary>
    public abstract class  BasePositionConverter: IPositionConverter
    {
        private char[] _arrChessRows = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' };
        private const int _lMaxChessRow = 8;
        private const int _boardSize = 8;

        public virtual int BoardSize
        {
            get { return _boardSize; }
        }

        /// <summary>
        /// Tries to parse chess position
        /// </summary>
        protected bool TryParseChessPosition(string sPosition, out Position pos)
        {
            pos = Position.Empty;

            // basic validation
            if (sPosition.Length != 2)
                return false;
            if (char.IsLetter(sPosition[0]) == false)
                return false;
            if (char.IsDigit(sPosition[1]) == false)
                return false;

            // try to convert column
            int? column = ConvertColumn(sPosition[0]);
            if (column.HasValue == false)
                return false;
            int col = column.Value - 1;

            // try to convert row
            int row = 0;
            if (int.TryParse(sPosition[1].ToString(), out row) == false)
                return false;
            if (row < 1 || row > _lMaxChessRow)
                return false;
            row = row - 1;

            pos = new Position(row, col);
            return true;
        }

        /// <summary>
        /// Tries to convert chess column position
        /// </summary>
        private int? ConvertColumn(char c)
        {
            c = char.ToUpper(c);
            for (int row = 0; row < _arrChessRows.Length; row++)
            {
                if (_arrChessRows[row] == c)
                    return row + 1;
            }

            return null;
        }

        /// <summary>
        /// The main parsing method
        /// </summary>
        public abstract bool TryParse(string sPosition, out Position pos);


        /// <summary>
        /// Converts position to chess coordinates
        /// </summary>
        protected string ToChessPosition(Position pos)
        {
            string s = string.Empty;
            s += char.ToLower(_arrChessRows[pos.Col]);
            s += (pos.Row + 1).ToString();
            return s;
        }

        /// <summary>
        /// The main writing position
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="bChess"></param>
        /// <returns></returns>
        public virtual string PositionToString(Position pos, bool bChess)
        {
            if (bChess == true)
                return ToChessPosition(pos);
            else
                throw new NotImplementedException();
        }
    }
}
